package org.ar.xmling.dom;

import java.util.ArrayList;
import java.util.List;

import org.ar.xmling.dom.processors.XMLTagAndAttributeProcessor;

public class XMLTag extends XMLTagAndAttributeProcessor {

  private String name;
  private String value;

  public XMLTag(String name) {
    this.name = name;
  }

  public List<XMLTagAttribute> attributes() {
    return attributes;
  }

  public boolean addToAttributes(XMLTagAttribute attribute) {
    if (attributes != null) {
      return attributes.add(attribute);
    }
    return false;
  }

  public boolean removeFromAttributes(XMLTagAttribute attribute) {
    if (attributes != null) {
      return attributes.remove(attribute);
    }
    return false;
  }

  public List<XMLTagAttribute> createAttributesList() {
    return attributes = new ArrayList<XMLTagAttribute>();
  }

  public List<XMLTagAttribute> createAttributesList(List<XMLTagAttribute> attributes) {
    return this.attributes = attributes;
  }

  public List<XMLTag> tags() {
    return tags;
  }

  public boolean addToTags(XMLTag tag) {
    if (tags != null) {
      return tags.add(tag);
    }
    return false;
  }

  public boolean removeFromTags(XMLTag tag) {
    if (tags != null) {
      return tags.remove(tag);
    }
    return false;
  }

  public List<XMLTag> createTagsList() {
    return tags = new ArrayList<XMLTag>();
  }

  public List<XMLTag> createTagsList(List<XMLTag> tags) {
    return this.tags = tags;
  }

  public String print() {
    // generate name
    StringBuilder result = new StringBuilder("<").append(name);
    // generate name with attributes
    for (XMLTagAttribute attr : attributes) {
      result.append(" ");
      result.append(attr.print());
    }
    if ((tags == null || tags.isEmpty()) && (value == null || value.isEmpty())) {
      result.append("/>");
    } else {
      result.append(">");
      // put tag body (other tags)
      for (XMLTag tag : tags) {
        result.append(tag.print());
      }
      result.append(value != null ? value : "");
      // close tag
      result.append("</").append(name).append(">");
    }
    return result.toString();
  }

  public String getName() {
    return name;
  }

  public String getValue() {
    return value;
  }

  public void setValue(String value) {
    this.value = value;
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = super.hashCode();
    result = prime * result + ((name == null) ? 0 : name.hashCode());
    result = prime * result + ((value == null) ? 0 : value.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) return true;
    if (!super.equals(obj)) return false;
    if (getClass() != obj.getClass()) return false;
    XMLTag other = (XMLTag) obj;
    if (name == null) {
      if (other.name != null) return false;
    } else if (!name.equals(other.name)) return false;
    if (value == null) {
      if (other.value != null) return false;
    } else if (!value.equals(other.value)) return false;
    return true;
  }

}
